﻿using JetBrains.Annotations;
using SSPivot.Common.Helpers;
using SSPivot.Data.Entities;
using SSPivot.Data.MultiTenancy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace SSPivot.AspNetCore.Abstractions.Data
{
    public class EntityHelper
    {
        public static bool IsMultiTenant<TEntity>()
        where TEntity : IEntity
        {
            return IsMultiTenant(typeof(TEntity));
        }

        public static bool IsMultiTenant(Type type)
        {
            return typeof(ITenantEntity).IsAssignableFrom(type);
        }
        
        public static bool IsEntity([NotNull] Type type)
        {
            Check.NotNullVoid(type, nameof(type));
            return typeof(IEntity).IsAssignableFrom(type);
        }

        public static bool IsEntityWithId([NotNull] Type type)
        {
            foreach (var interfaceType in type.GetInterfaces())
            {
                if (interfaceType.GetTypeInfo().IsGenericType &&
                    interfaceType.GetGenericTypeDefinition() == typeof(IEntity<>))
                {
                    return true;
                }
            }

            return false;
        }

        public static bool HasDefaultId<TKey>(IEntity<TKey> entity)
        {
            if (EqualityComparer<TKey>.Default.Equals(entity.Id, default))
            {
                return true;
            }

            //Workaround for EF Core since it sets int/long to min value when attaching to dbcontext
            if (typeof(TKey) == typeof(int))
            {
                return Convert.ToInt32(entity.Id) <= 0;
            }

            if (typeof(TKey) == typeof(long))
            {
                return Convert.ToInt64(entity.Id) <= 0;
            }

            return false;
        }

        public static void TrySetId<TKey>(
        IEntity<TKey> entity,
        Func<TKey> idFactory)
        {
            ObjectHelper.TrySetProperty(
                entity,
                x => x.Id,
                idFactory
            );
        } 
    }
}
